package main

import (
	"fmt"
	"sync"
)

/**
goruntine 并发：如何解决主的goruntine在子协程结束后自动结束
WaitGroup提供了三个很有用的函数
	Add:  开启计数器，每添加一个任务，计数器+1
	Done: 任务完成，计数器就-1
	Wait: 阻塞io, 等待非主线程任务完成
ps：Add的数量 需要和 Done的数量 相等，否则会报错：deadLock(死锁)
*/
var wg sync.WaitGroup

func hello(i int) {
	fmt.Println("hello: ", i)
	defer wg.Done()
}

// goruntine的执行顺序是不固定的!
// goruntine的执行是互相竞争CPU资源运行!
func main() { // 开启了一个主goruntine去执行 main 函数
	// 1. 开启goruntine
	for i := 1; i <= 10; i++ {
		wg.Add(1)   // 计数器 + 1
		go hello(i) // 开启了一个goruntine去执行 hello 函数
	}
	fmt.Println("hello main")
	wg.Wait()

	// 2. goexit return exit的区别
	// runtime.Goexit 提前退出go程序
	// return 返回当前函数
	// os.Exit   退出当前进程
	go func() {
		fmt.Println("子go程中的匿名函数")
	}()
}
